const fs = require('fs')
const {
	sleep,
	request,
	sleepRandom,
	getDocument,
	getWindow,
	getParams,
	getResponse,
	getMaxResponse,
	getMSTime,
} = require('../utils')
const _CrawlerMongo = require('../utils/config/CrawlerMongo')
const _mongo = new _CrawlerMongo()
const _TaskBaseFactory = require('../utils/task/TaskBaseFactory')

const _host = 'http://verycd.gdajie.com/'
const _typeUrl = 'http://verycd.gdajie.com/#{type}/page'
const _typeListUrl = 'http://verycd.gdajie.com/#{type}/#{page}'

async function getItemDocs(typeId, currentPage) {
	let typeListUrl = _typeListUrl.replace('#{type}', typeId)
		.replace('#{page}', `page${currentPage}`)
	let window = await getMaxResponse(getWindow, typeListUrl, {
		ms: getRandomMSSleep()
		// ms: 0
	})
	let document = window.document
	return document.querySelectorAll('#main ul li')
}

async function handler() {
	let {
		query,
		num,
		total,
		amount,
		currentIdx = 0,
		currentPage,
	} = this.__task
	let {
		size,
		typeId,
		typeName,
		totalPage,
	} = query
	if (amount == 0 || total == 0) {
		let gdajieInfo = await getGdajieInfo(typeId)
		amount = total = gdajieInfo.amount
	}
	num = num == 0 ? num : num - 1
	let itemDocs = await getItemDocs.call(this, typeId, currentPage)
	while (itemDocs && itemDocs.length > 0) {
		for (let i = currentIdx; i < itemDocs.length; i++) {
			currentIdx = i
			num += 1
			this.__task.update({
				currentIdx,
				num,
				currentPage,
				amount,
				total,
			})
			let itemDoc = itemDocs[i]
			let titleA = itemDoc.querySelector('div.list_info h4 a')
			// let titleA = itemDoc.querySelector('div.list_info h4 a')
			if (titleA && titleA.title)
				await saveItem.call(this, itemDoc, typeId, typeName)
		}
		currentIdx = 0
		currentPage += 1
		itemDocs = await getItemDocs.call(this, typeId, currentPage)
	}
	return num == total
}

/**
 * 保存资源信息
 * @param  {[type]} songMenuA [description]
 * @return {[type]}           [description]
 */
async function saveItem(itemDoc, typeId, typeName) {
	let item = await getItemInfo(itemDoc, typeId, typeName)
	this.__task.update({
		item,
	})
	if (item && item._id)
		return item
	delete item._id
	item.modify_time = getMSTime()
	let collection = await _mongo.getCollection(typeId)
	let {
		lastErrorObject,
		value,
		ok,
	} = await collection.findOneAndUpdate({
		id: item.id,
		title: item.title,
		type_id: item.type_id,
		category: item.category,
	}, {
		$set: item
	})
	if (!value || !value._id)
		return collection.insertOne(item)
	return item
}

async function getItemInfo(itemDoc, type_id, type_name) {
	let titleA = itemDoc.querySelector('div.list_info h4 a')
	let title = titleA && titleA.title || ''
	let url = titleA && titleA.href || ''
	let infoHTML = itemDoc.querySelector('div.list_info')
	let info_html = infoHTML && infoHTML.innerHTML && infoHTML.innerHTML.replace(/[\n\r]/g, '') || ''
	let id = url.replace(/[^\d]/g, '')
	let collection = await _mongo.getCollection(type_id)
	let itemInfo = await collection.findOne({
		id,
	})
	if (itemInfo && itemInfo._id)
		return itemInfo
	// http://verycd.gdajie.com/topics/2983763/
	let window = await getMaxResponse(getWindow, url, {
		ms: getRandomMSSleep()
		// ms: 0
	});
	let document = window.document
	let navAList = document.querySelectorAll('div#nav a')
	let navA = navAList[navAList.length - 1]
	let category = navA.href && navA.href.replace('http://verycd.gdajie.com/', '')
		.replace(/\/page\d*/, '')
	let category_name = navA && navA.innerHTML
	let descDiv = document.querySelector('div#main div.description')
	let desc = descDiv && descDiv.innerHTML || ''
	let detailListDiv = document.querySelectorAll('#emuleFile tbody tr')
	let source_list = []
	for (let i = 1; i < detailListDiv.length; i++) {
		let tr = detailListDiv[i]
		let tdArr = tr.querySelectorAll('td')
		let tdInfoA = tdArr[0] && tdArr[0].querySelector('a')
		let size = tdArr[1] && tdArr[1].innerHTML
		let title = tdInfoA && tdInfoA.title
		let detailUrl = tdInfoA && tdInfoA.href
		let download_url = ''
		if (detailUrl) {
			// http://www.verycd.gdajie.com/detail.htm?id=2123455
			// let window = await getMaxResponse(getWindow, detailUrl, {
			// 	ms: getRandomMSSleep()
			// });
			// let document = window.document
			// let tables = document.querySelectorAll('#detail table')
			// let table = tables[1]

			let table = await getTable(detailUrl)
			let ct = 0
			while ((!table || !table.querySelector) && ct < 10) {
				ct += 1
				table = await getTable(detailUrl)
			}
			let sourceHTML = table && table.querySelector('tbody tr td div center span') || ''
			download_url = sourceHTML.innerHTML || ''
		}
		source_list.push({
			title,
			url: detailUrl,
			size,
			download_url,
		})
	}
	return {
		id,
		url,
		title,
		type_id,
		type_name,
		category,
		category_name,
		// info_html,
		source_list,
		// desc,
	}
}

async function getTable(detailUrl) {
	// http://www.verycd.gdajie.com/detail.htm?id=2123455
	let window = await getMaxResponse(getWindow, detailUrl, {
		ms: getRandomMSSleep()
		// ms: 0
	});
	let document = window.document
	let tables = document.querySelectorAll('#detail table')
	return tables[1]
}

class GdajieTaskFactory extends _TaskBaseFactory {
	constructor(args) {
		super(args)
		this.typeId = 'gdajie'
		this.cateId = 'fetch'
		this._id = process.argv[2]
		this.init = process.argv[3]
		this.handler = handler
	}

	__init() {
		return init.call(this)
	}
}

const task = new GdajieTaskFactory()
task.run()

async function getGdajieInfo(typeId) {
	let typeUrl = _typeUrl.replace('#{type}', typeId)
	let window = await getMaxResponse(getWindow, typeUrl, {
		ms: getRandomMSSleep()
		// ms: 0
	});
	let document = window.document
	let totalList = document.querySelectorAll('div#accordion a.menu')
	let pageInfoDiv = document.querySelector('div.pager')
	let arr = pageInfoDiv.querySelectorAll('div a')
	let totalPage = 0
	for (let i = 0; i < arr.length; i++) {
		let pageDiv = arr[i]
		let page = pageDiv.innerHTML
		page = parseInt(page.replace(/[^\d]/g, ''))
		if (page > 200) {
			totalPage = page
			break;
		}
	}
	let amount = 0
	for (let i = 0; i < totalList.length; i++) {
		let totalA = totalList[i]
		if (totalA.href.indexOf(typeId) > -1) {
			let html = totalA.innerHTML
			html = html.replace(/[^\d]/g, '')
			amount = parseInt(html)
		}
	}
	return {
		amount,
		totalPage,
		currentPage: 1,
	}
}

async function init() {
	let _id = this._id
	let init = this.init
	if (_id && init == 'init') {
		await _Task.findOneAndUpdate({
			_id,
		}, {
			currentIdx: 0,
			currentPage: 1,
		});
	}
}

function getRandomMSSleep() {
	let ms = parseInt(Math.random() * 100 * 1000)
	return ms < 10000 ? 20000 : ms
}